package com.nowar.common.util;


import com.nowar.common.util.thread.SimpleThreadFactory;
import com.nowar.common.util.thread.DefaultUncaughtExceptionHandler;
import com.nowar.common.util.thread.ThreadPool;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.InitializingBean;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: 谢无殇。
 * @Date : 2023-03-05 23:54
 */
@Getter
@Setter
public class JdkThreadPool implements ThreadPool, InitializingBean {
    /**
     * 核心线程数
     */
    private int corePoolSize = Runtime.getRuntime().availableProcessors() * 8;
    /**
     * 存活时间
     */
    private int keepAliveTime = 180;
    /**
     * 队列大小
     */
    private int queueSize = 1024;
    /**
     * 阻塞队列
     */
    private BlockingQueue<Runnable> workQueue;
    /**
     * 拒绝策略
     */
    private RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
    /**
     * 线程池
     */
    private ThreadPoolExecutor poolExecutor;

    /**
     * 线程名称
     */
    private String threadName;

    /**
     * 子线程异常处理
     */
    private DefaultUncaughtExceptionHandler uncaughtExceptionHandler = new DefaultUncaughtExceptionHandler();

    public JdkThreadPool() {
    }

    @Override
    public void execute(Runnable runnable) {
        poolExecutor.execute(runnable);
    }

    @Override
    public void execute(Runnable runnable, String name) {

    }

    @Override
    public ThreadPoolExecutor getExecutor() {
        return poolExecutor;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        SimpleThreadFactory var1;
        if (threadName == null) {
            //设置线程工厂
            var1 = new SimpleThreadFactory("defaultPool", uncaughtExceptionHandler);
        } else {
            var1 = new SimpleThreadFactory(threadName, uncaughtExceptionHandler);

        }
        poolExecutor = new ThreadPoolExecutor(corePoolSize, corePoolSize,
                keepAliveTime, TimeUnit.SECONDS, getWorkQueue(), var1, handler);
    }

    public String getThreadName() {
        return threadName;
    }

    public void setThreadName(String threadName) {
        this.threadName = threadName;
    }

    public BlockingQueue<Runnable> getWorkQueue() {
        if (workQueue == null) {
            workQueue = new ArrayBlockingQueue<>(queueSize, false);
        }
        return workQueue;
    }

    public void setWorkQueue(BlockingQueue<Runnable> workQueue) {
        this.workQueue = workQueue;
    }

    public RejectedExecutionHandler getHandler() {
        return handler;
    }

    public void setHandler(RejectedExecutionHandler handler) {
        this.handler = handler;
    }

    public void shutdown() {
        if (poolExecutor != null) {
            poolExecutor.shutdown();
        }
    }

    /**
     * 拒绝策略
     */
    /*
    public static class HandlerPolicy implements RejectedExecutionHandler {

        public HandlerPolicy() {
        }

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                    " rejected from " +
                    e.toString());
        }
    }*/


}
